/*
 * dbasesRoot.java
 *
 * Created on May 18, 2006, 2:08 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 * 
 * 13, Feb 2009
 *              the method processTreeHierarchy now prevents to process a null
 *              databaseObject.
 * 22, Feb 2011
 *              Method rump up; the global variable sDriver was renamed to sUrl in order to describe more accuretly its function as a
 *              connection argument.
 *              Begin with multiple sql driver support.
 * 19, Mar 2012
 *              In order to transition to the factory pattern, the class converted to abstract
 * 10, Feb 2014 
 *              Some trivial changes made in order to make the code compatible with Java 1.7.
 */

package portfolio.dbHost;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import portfolio.dbHost.dataBases.DBase;
import portfolio.configMessage.configMessageEvent;
import portfolio.configMessage.configMessageFrame;
import portfolio.dbHost.dataBases.MysqlDBase;

import portfolio.mainScreen;

/**
 *
 * @author ACA
 */
public class MysqlHost extends Host //implements configMessageListener, MouseListener
{
    
    /**
     *
     * @param e 
     */
    public void okSelected     (configMessageEvent e)
    {
        configMessageFrame msgFrame = super.getMsgFrame();
        mainScreen mainFrame = super.getMainFrame ();
        try {
            String sCommand = msgFrame.getSQLStatementMnemonic();

            if        (sCommand.equals(Host.ACTION_LOGON_DB)) {
                Vector vConnectParams = msgFrame.getSqlCreateParams();
                String sUrl            = vConnectParams.get(0).toString();
                String sHost           = vConnectParams.get(1).toString();
                String sDataSourceName = vConnectParams.get(2).toString();
                String sUser           = vConnectParams.get(3).toString();
                String sPassword       = vConnectParams.get(4).toString();
                super.setUrl (sUrl);
                super.setHost (sHost);
                super.setDataSourceName(sDataSourceName);
                super.setUser(sUser);
                super.setPassword(sPassword);
                super.setConnection (this.connectToDB (Host.DB_TYPE_MYSQL, sUrl, sHost, sDataSourceName, sUser, sPassword));

                this.printConnectionMetadata();

                this.buildDBTree ();
                this.setDBTree (mainFrame.getDBasePanel ());
                mainFrame.displayMessage("Host.okSelected 81", Host.ACTION_LOGON_DB + " successful.");
            } else if (sCommand.equals(Host.ACTION_CREATE_DB)) {
                String sDBName = msgFrame.getFieldName();
                
                this.createDB (sDBName);
                this.buildDBTree();
                
                this.updateDBTree (); //mainFrame.getDBasePanel ());
                mainFrame.displayMessage("Host.okSelected 88", this.ACTION_CREATE_DB + " " + sDBName + " successful.");
            }
        } catch (Exception ex) {            
              mainFrame.displayMessage("Host.okSelected 91", ex.getMessage());
//0j0            connection = null;
        }
        msgFrame.dispose();
    }
    /*******************************************************************************/
    /**
     * Creates a new instance of DBase
     * @param mainFrameParam 
     * @throws java.lang.Exception 
     */
    public MysqlHost (mainScreen mainFrameParam) throws Exception
    {
        super (mainFrameParam);
        super.setDBtype(Host.DB_TYPE_MYSQL);
    } /* end constructor DBase */
    /**
     *
     * @param sUrlParam
     * @param sHostParam
     * @param sDataBaseParam
     * @param sUserParam
     * @param sPasswdParam
     * @return
     * @throws Exception
     */
    public static Connection connectToMysqlDB (String sUrlParam,
                                               String sHostParam,
                                               String sDataBaseParam,
                                               String sUserParam,
                                               String sPasswdParam) throws Exception
    {
        Class.forName ("com.mysql.jdbc.Driver").newInstance ();
        String sLogonLine = sUrlParam         +
                     "//"         + sHostParam +
                     "/"          + sDataBaseParam +
                     "?user="     + sUserParam +
                     "&password=" + sPasswdParam;
        return DriverManager.getConnection (sLogonLine);

    }
    /**
     *
     * @param iDbTypeParam
     * @param sUrl
     * @param sHost
     * @param sDataSourceName
     * @param sUser
     * @param sPasswd
     * @return
     * @throws Exception
     */
    public Connection connectToDB (int iDbTypeParam, // <----- & non static
                                          String sUrl,
                                          String sHost, 
                                          String sDataSourceName,
                                          String sUser,
                                          String sPasswd) throws Exception
    {
        Connection tmpConnection = null;
        
	try {
            if (iDbTypeParam == DB_TYPE_MYSQL) {
                String sDataBase = sDataSourceName;
                tmpConnection = connectToMysqlDB (sUrl, sHost, sDataBase, sUser, sPasswd);
            } else {
                throw new Exception ("Unknown database.");
            }

	}
	catch (Exception ex) {
	    throw new Exception (ex);
	}
        
        return tmpConnection;
    } /* end connectToDB method */
    /**
     *
     *
     */
//    private int getDBType (String sURL)
//    {
//        sURL.toLowerCase();
//        if (sURL.contains(":" + DB_DRIVER_MYSQL + ":") == true) {
//            return DB_TYPE_MYSQL;
//        }
//        return DB_TYPE_UNKNOWN;
//    }
    /**
     * 
     * @throws java.lang.Exception 
     */
    public void buildDBTree ( ) throws Exception //Connection connectionParam) throws Exception
    {
        dataBases   = null;
        try {
            vDBases = this.showDBs ();
            if (vDBases == null)
                return;
            int iDBType = super.getDBType();
            if (iDBType == DB_TYPE_MYSQL) {
                vDBases.remove(Host.DB_DRIVER_MYSQL);
                int iDBasesCount = vDBases.size();
                if (iDBasesCount > 0) {
                    dataBases = new DBase [iDBasesCount];
                    for (int iIdx = 0; iIdx < iDBasesCount; iIdx++) {
                        dataBases [iIdx] = new MysqlDBase (this, vDBases.get(iIdx).toString());
                    }
                }
            } 
        } catch (SQLException e) {
            throw new Exception (e);
        }            
    }
    /**
     * the mysql statement "show databases" is not conformant with SQL standard
     */
    public static Vector showDBs (Connection connectionParam) throws Exception
    {
        if (connectionParam == null)
            throw new Exception ("null connection");

        Statement statement = null;
        Vector outVector = new Vector ();
        try {
            statement = connectionParam.createStatement();
            ResultSet resultSet = statement.executeQuery ("SHOW DATABASES;");
//            ResultSetMetaData rsmd = resultSet.getMetaData ();

            if (resultSet.next()) {
                do {
                    String sTmp = resultSet.getString (1);//.toLowerCase();

                    if (!outVector.contains(sTmp)) {
                        outVector.addElement (sTmp);
                    }
                } while (resultSet.next ());
            } //else {
                //outVector = null;
            //}
        }
        catch (SQLException sqlex) {
            throw new Exception ("portfolioDB::showDatabases: " + sqlex);
        }
        return outVector;
    } /* end method showDatabases */
    /**
     * 
     */
    public Vector showDBs () throws Exception
    {
        int iDBType = super.getDBType();
        if (iDBType == DB_TYPE_MYSQL) {
            return MysqlHost.showDBs (super.getConnection());
        } 

        return null;
    }
} /* end class DBase */

